package com.gy.service.impl;


import com.gy.config.AliOSSConfig;
import com.gy.service.ImageMergeService;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.BaseFont;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.List;

@Service
@Slf4j
public class ImageMergeServiceImpl implements ImageMergeService {

    @Autowired
    private AliOSSConfig aliOSSConfig;

    /**
     * 将图片序列合并为PDF
     */
    @Override
    public byte[] mergeImagesToPdf(List<String> imageUrls,
                                   Map<String, Object> coverData,
                                   List<Map<String, Object>> tableOfContents,
                                   Boolean showCover,
                                   Boolean showTableOfContents) throws DocumentException, IOException {

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        Document document = new Document(PageSize.A4);
        PdfWriter writer = PdfWriter.getInstance(document, outputStream);

        document.open();

        InputStream fontStream = this.getClass().getClassLoader()
                .getResourceAsStream("fonts/SourceHanSerifTC-Regular.otf");
        if (fontStream == null) {
            throw new FileNotFoundException("字体文件未找到，请检查 fonts/SourceHanSerifCN-Regular.otf 是否存在");
        }

        // 将 InputStream 转为 byte[]
        byte[] fontBytes;
        try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
            byte[] temp = new byte[1024];
            int n;
            while ((n = fontStream.read(temp)) != -1) {
                buffer.write(temp, 0, n);
            }
            fontBytes = buffer.toByteArray();
        }

        BaseFont baseFont = BaseFont.createFont(
                "SourceHanSerifTC-Regular", // 虚拟名，可以随便写
                BaseFont.IDENTITY_H,
                BaseFont.NOT_EMBEDDED,
                BaseFont.CACHED,
                fontBytes,
                null
        );



        Font font = new Font(baseFont, 14, Font.NORMAL);
        Font titleFont = new Font(baseFont, 24, Font.BOLD);
        Font normalFont = new Font(baseFont, 16, Font.NORMAL);
        Font smallFont = new Font(baseFont, 12, Font.NORMAL);

        try {
            // 1. 添加封面页
            if (Boolean.TRUE.equals(showCover)) {
                addCoverPage(document, coverData, titleFont, normalFont);
                document.newPage();
            }

            // 2. 添加目录页
            if (Boolean.TRUE.equals(showTableOfContents) && tableOfContents != null) {
                addTableOfContentsPage(document, tableOfContents, titleFont, normalFont);
                document.newPage();
            }

            // 3. 添加图片页面
            for (String imageUrl : imageUrls) {
                try {
                    addImagePage(document, imageUrl);
                    document.newPage();
                } catch (Exception e) {
                    log.warn("添加图片页面失败: {}", imageUrl, e);
                }
            }

        } finally {
            document.close();
        }

        return outputStream.toByteArray();
    }

    /**
     * 添加封面页
     */
    private void addCoverPage(Document document, Map<String, Object> coverData, Font titleFont, Font normalFont) throws DocumentException {
        // 添加标题
        String title = (String) coverData.getOrDefault("title", "附件材料");
        Paragraph titleParagraph = new Paragraph(title, titleFont);
        titleParagraph.setAlignment(Element.ALIGN_CENTER);
        titleParagraph.setSpacingAfter(30f);
        document.add(titleParagraph);

        // 添加副标题
        String subtitle = (String) coverData.get("subtitle");
        if (subtitle != null && !subtitle.isEmpty()) {
            Paragraph subtitleParagraph = new Paragraph(subtitle, normalFont);
            subtitleParagraph.setAlignment(Element.ALIGN_CENTER);
            subtitleParagraph.setSpacingAfter(50f);
            document.add(subtitleParagraph);
        }

        // 添加申报信息
        @SuppressWarnings("unchecked")
        Map<String, Object> declarationInfo = (Map<String, Object>) coverData.get("declarationInfo");
        if (declarationInfo != null) {
            @SuppressWarnings("unchecked")
            Map<String, String> labels = (Map<String, String>) declarationInfo.get("labels");
            String person = (String) declarationInfo.get("person");
            String unit = (String) declarationInfo.get("unit");

            if (labels != null && person != null && !person.isEmpty()) {
                Paragraph personParagraph = new Paragraph(labels.get("person") + "：" + person, normalFont);
                personParagraph.setAlignment(Element.ALIGN_CENTER);
                personParagraph.setSpacingAfter(20f);
                document.add(personParagraph);
            }

            if (labels != null && unit != null && !unit.isEmpty()) {
                Paragraph unitParagraph = new Paragraph(labels.get("unit") + "：" + unit, normalFont);
                unitParagraph.setAlignment(Element.ALIGN_CENTER);
                unitParagraph.setSpacingAfter(20f);
                document.add(unitParagraph);
            }
        }
    }

    /**
     * 添加目录页
     */
    private void addTableOfContentsPage(Document document, List<Map<String, Object>> tableOfContents, Font titleFont, Font normalFont) throws DocumentException {
        // 添加目录标题
        Paragraph tocTitle = new Paragraph("目录", titleFont);
        tocTitle.setAlignment(Element.ALIGN_CENTER);
        tocTitle.setSpacingAfter(30f);
        document.add(tocTitle);

        // 添加目录项
        for (Map<String, Object> item : tableOfContents) {
            String title = (String) item.get("title");
            Object pageNumberObj = item.get("pageNumber");
            String pageNumber = pageNumberObj != null ? pageNumberObj.toString() : "1";

            Paragraph tocItem = new Paragraph(title + " ........................ " + pageNumber, normalFont);
            tocItem.setSpacingAfter(10f);
            document.add(tocItem);
        }
    }

    /**
     * 添加图片页面
     */
    private void addImagePage(Document document, String imageUrl) throws Exception {
        try {
            // 从URL加载图片
            URL url = new URL(imageUrl);
            BufferedImage bufferedImage = ImageIO.read(url);

            if (bufferedImage == null) {
                throw new IOException("无法读取图片: " + imageUrl);
            }

            // 将BufferedImage转换为iText Image
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "jpg", baos);
            Image image = Image.getInstance(baos.toByteArray());

            // 计算图片缩放比例以适应A4页面
            float pageWidth = PageSize.A4.getWidth() - 72; // 减去边距
            float pageHeight = PageSize.A4.getHeight() - 72; // 减去边距

            float imageWidth = image.getWidth();
            float imageHeight = image.getHeight();

            float scaleX = pageWidth / imageWidth;
            float scaleY = pageHeight / imageHeight;
            float scale = Math.min(scaleX, scaleY);

            image.scalePercent(scale * 100);

            // 居中显示
            image.setAlignment(Element.ALIGN_CENTER);

            document.add(image);

        } catch (Exception e) {
            log.error("添加图片页面失败: {}", imageUrl, e);
            throw e;
        }
    }

    /**
     * 批量获取PDF图片列表
     */
    public Map<String, Object> batchGetPdfImages(List<String> pdfPaths) {
        List<String> allImageUrls = new ArrayList<>();
        int totalPages = 0;

        for (String pdfPath : pdfPaths) {
            try {
                // 这里需要调用现有的获取PDF图片的方法
                // 假设有一个方法可以根据路径获取图片列表
                List<String> imageUrls = getPdfImagesByPath(pdfPath);
                allImageUrls.addAll(imageUrls);
                totalPages += imageUrls.size();
            } catch (Exception e) {
                log.warn("获取PDF图片失败: {}", pdfPath, e);
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("imageUrls", allImageUrls);
        result.put("totalPages", totalPages);
        return result;
    }

    /**
     * 根据PDF路径获取图片列表（需要实现）
     */
    private List<String> getPdfImagesByPath(String pdfPath) {
        // 这里需要实现根据PDF路径获取对应图片列表的逻辑
        // 可以查询数据库或者直接从OSS获取
        List<String> imageUrls = new ArrayList<>();

        try {
            // 解析路径，获取基础路径
            String basePath = extractBasePath(pdfPath);

            // 根据基础路径构建图片URL列表
            // 这里需要根据你的实际存储结构来实现
            String bucketName = aliOSSConfig.getBucketName();
            String endpoint = aliOSSConfig.getEndpoint();

            // 假设图片按页码命名：page-1.jpg, page-2.jpg, ...
            // 这里需要知道总页数，可以从数据库查询或者通过其他方式获取
            int pageCount = getPageCountByPath(basePath);

            for (int i = 1; i <= pageCount; i++) {
                String imageUrl = "https://" + bucketName + "." + endpoint + "/" + basePath + "page-" + i + ".jpg";
                imageUrls.add(imageUrl);
            }

        } catch (Exception e) {
            log.error("构建图片URL列表失败: {}", pdfPath, e);
        }

        return imageUrls;
    }

    /**
     * 从PDF路径提取基础路径
     */
    private String extractBasePath(String pdfPath) {
        // 实现路径解析逻辑
        // 例如：从 "https://bucket.endpoint.com/pdf-images/uuid/page-1.jpg"
        // 提取 "pdf-images/uuid/"
        if (pdfPath.contains("pdf-images/")) {
            int startIndex = pdfPath.indexOf("pdf-images/");
            int endIndex = pdfPath.lastIndexOf("/") + 1;
            return pdfPath.substring(startIndex, endIndex);
        }
        return pdfPath;
    }

    /**
     * 根据基础路径获取页数
     */
    private int getPageCountByPath(String basePath) {
        // 这里需要查询数据库获取页数
        // 或者通过其他方式获取
        // 暂时返回默认值
        return 1;
    }
}
